---------------------------------------- Chapitre VII - Hachage ----------------------------------------
Deux exemples de protection basée sur des hash MD5 - 2/2
II - DEUXIEME CAS : Shadow Defender
Cible : Shadow Defender v1.1.0.331
Editeur : ShadowDefender.com
En plus d’être intéressant, il peut être pratique pour le reverse . C’est un peu comme une machine virtuelle, mais c’est votre propre système qui est lancé sous la VM.
Une fois installé et redémarré, l’icône se trouve en barre des tâches. Quand on fait un clic droit sur "Open Shadow defender" un petit nag nous rappelle que c’est une version trial et nous propose de s’enregistrer. Voici notre boîte d’ enregistrement :
Premièrement, on remarque qu’on n’a pas le choix de la longueur, il suffit de remplir les cases. De même, le bouton "OK" ne semble s’activer qu’à la saisie d’un serial valide. Le contrôle doit donc se faire "en live".
Lancez Olly et attachez vous au processus defender.exe (ça évite de quitter et relancer ), n’oubliez pas de faire F9 pour relancer le soft après la pause à l’attachement.
Les SDR ne nous donnent rien de concret. Par contre, comme on a scanné avec PEiD et Kanal avant de commencer, on a un indice intéressant :
Il n’y a qu’une signature. Si c’est utilisé pour le serial, on tombera forcément dessus, c’est un bon point. Allons à cette adresse et remontons jusqu’au début de la routine en 0040FD68. On voit que celle-ci est appelée par 2 CALLs. Si on va à ceux-ci, on s'aperçoit qu'ils sont dans la même routine tous les deux, on va donc poser un BP en début de celle-ci ainsi qu'un label (touche " : "). Pour moi "HashMD5" :
On va aussi regarder du côté des imports (CTRL+N) et chercher "GetDlgItem", notre serial étant surement vérifié en direct :
Names in Defender, item 308 Address=004564EC Section=.rdata Type=Import (Known) Name=USER32.GetDlgItem
Un petit " Set Breakpoint on every reference" et ressaisissons la dernière lettre du serial pour voir si on est sur la bonne piste.
On break directement sur un "GetDlgItem" ,
traçons gentiment en step over, tout en observant les registres et la pile, et nous voyons que les contrôles contenant notre serial sont
récupérés :
0012CC24 01245730 UNICODE "abcde"
0012CC28 012470B0 UNICODE "fghij"
0012CC2C 01247FF0 UNICODE "klmno"
0012CC30 01248028 UNICODE "pqrst"
0012CC34 01248060 UNICODE "uVWXy
On continue de tracer, les différents CALLs recomposent le serial, on le suit via la pile, jusqu’à cette comparaison :
00410F52 |. 8378 F4 19 CMP DWORD PTR DS:[EAX-C],19
00410F56 |. 75 20 JNZ SHORT Defender.00410F78
00410F58 |. 6A 00 PUSH 0
00410F5A |. 50 PUSH EAX
00410F5B |. E8 2B330000 CALL Defender.0041428B
00410F60 |. 59 POP ECX
00410F61 |. 59 POP ECX
00410F62 |. 85C0 TEST EAX,EAX
00410F64 |. 74 12 JE SHORT Defender.00410F78
La longueur de notre serial reconstitué est comparée à 19h (soit 25d, la longueur
à rentrer). Sinon on saute le CALL 0041428B, et on peut en profiter pour voir que si EAX vaut 0 à
la sortie de ce CALL, on va au même endroit .
On continue avec F8 (et avec l’œil alerte )
jusqu’ici :
004142DF . E8 F04D0200 CALL Defender.004390D4
004142E4 . 8D85 9C000000 LEA EAX,DWORD PTR SS:[EBP+9C] ; |
004142EA . 50 PUSH EAX
; |Arg1
004142EB . E8 633B0200 CALL Defender.00437E53 ; \Defender.00437E53
004142F0 . 83C4 1C ADD ESP,1C
004142F3 . 33FF XOR EDI,EDI
004142F5 . 83F8 19 CMP EAX,19
004142F8 . 0F85 A4000000 JNZ Defender.004143A2
Les 2 premiers CALLs font un CharUpper sur le serial, puis vérifient à nouveau la longueur.
On voit ensuite que notre serial est concaténé à la chaîne "V100" :
Ce qui me donne "ABCDEFGHIJKLMNOPQRSTUVWXYV100". On reprend le traçage, on voit que les 0Dh (13d) derniers caractères de la chaîne concaténée sont extraits (="QRSTUVWXYV100"), puis poussés en argument avant le CALL.HashMD5…mon label
Nul doute qu’on va breaker et que nous aurons le hash de note petite chaîne. Hashons celle-ci avec Keygenner Assistant par exemple, on obtient : "0FD5639B70DC1C22066D558AFA4A82CE".
On pose un petit BP en sortie du call et F9 jusqu’à revenir dessus, on continue de tracer et on arrive à cette boucle :
En suivant l’adresse du byte mis dans EAX, on tombe sur notre hash :
On va aller voir à l’adresse 004141B, en rentrant dans le CALL de la boucle. On remarque tout de suite un switch, qui va déterminer une valeur en fonction du byte placé dans EAX, au premier tour, pour OFh, on aura 53h :
0041417B /$ 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
0041417F |. 6A 1F PUSH 1F
00414181 |. 99 CDQ
00414182 |. 59 POP ECX
00414183 |. F7F9 IDIV ECX
00414185 |. 83FA 1E CMP EDX,1E ; Switch (cases 0..1E)
00414188 |. 77 7F JA SHORT Defender.00414209
0041418A |. FF2495 0F4241 JMP DWORD PTR DS:[EDX*4+41420F]
Je ne vous colle pas tout le tableau du switch, mais voilà le petit calcul.
En sortie de switch, on voit que la valeur obtenue est comparée au premier caractère du serial entré. Si ce n’est pas égal, on sort de la boucle. On incrémente ESI, qui sert ici de compteur pour les caractères du hash et du serial, et on recommence la boucle 16 fois (0x010h) avec les 16 bytes du hash, ce qui correspond aux 16 caractères restants de la chaîne concaténée : "ABCDEFGHIJKLMNOP".
Inversez le Flag Z à chaque passage sur le JNZ en 00414385 (sauf si par hasard, vous aviez la bonne
valeur ) pour pouvoir continuer à tracer.
On relève donc :
53h=S, 36h=6, 47h=G, 41h=A, 57h=W, 44h=D,37 h=7, 44h=D, 47h=G, 54 h=T, 32h=2, 52h=R, 43 h=C, 50h=P, 47h=G, 58 h=X
Soit "S6GAW-D7DGT-2RCPG-X"
Ajoutons-y la fin du premier serial entré "QRSTUVWXY", et réessayons après avoir retiré tous les BP avec : "S6GAW-D7DGT-2RCPG-XQRST-UVWXY"
Le bouton se dégrise, on valide et "It is Good! ".
Voilà, ces deux petits exemples d’utilisation d’un hash MD5 sont terminés. On peut voir que pour ce dernier, même s’il n’y avait pas de SDR, ni de message d’erreur ou de réussite, le MD5 étant utilisé et étant la seule signature détectée, on pouvait facilement trouver un point d'entrée au milieu de la routine.
Pour en faire le keygen, on peut simplement "ripper" le switch pour ne pas s’embêter. Faut savoir être fainéant
.
Je ne vous colle pas tout le code, vous n’allez pas le lire ,
mais la source est jointe
.